#! /usr/bin/python3
# -*- coding: UTF-8 -*-

if __name__ == "__main__":
	raise Exception("不支持从这里调用")

__version__ = "1.0"
__all__ = [
	"MouseChshHttpMultiPartBody"
]

from com.mousechsh.common.util.MouseChshMath import mousechsh_math_gen_uuid
from com.mousechsh.common.util.MouseChshCodeUtil import mousechsh_codec, mousechsh_code_util_type_bytes, \
	mousechsh_code_util_type_utf8string
from com.mousechsh.common.log.MouseChshLog import mousechsh_logging_data


class MouseChshHttpMultiPartBody:

	def __init__(self, multipart_split):
		self.__data = {}
		self.__multipart_split = multipart_split

	def set_multipart_split(self, value):
		self.__multipart_split = str(value)

	def get_multipart_split(self):
		return self.__multipart_split

	def gen_multipart_split(self):
		self.__multipart_split = '----' + mousechsh_math_gen_uuid()

	def get_content(self, key):
		if key in self.__data:
			if '' in self.__data[key]:
				if 'filename' in self.__data[key]:
					return self.__data[key]['']
				else:
					return mousechsh_codec(
						self.__data[key][''],
						source_type=mousechsh_code_util_type_bytes,
						target_type=mousechsh_code_util_type_utf8string
					)
		return None

	def get_filename(self, key):
		if key in self.__data:
			if '' in self.__data[key]:
				if 'filename' in self.__data[key]:
					return str(self.__data[key]['filename'])
		return None

	def parse(self, value):
		if isinstance( value, bytes ):
			self.__data = {}
			multipart_split = mousechsh_codec(
				self.__multipart_split,
				source_type=mousechsh_code_util_type_utf8string,
				target_type=mousechsh_code_util_type_bytes
			)
			multipart_split_start = b'--' + multipart_split + b'\r\n'
			if value.find(multipart_split_start) >= 0:
				value = value[value.find(multipart_split_start) + len(multipart_split_start):]
			multipart_split_ends = b'\r\n--' + multipart_split + b'--'
			if value.find(multipart_split_ends) >= 0:
				value = value[:value.find(multipart_split_ends)]
			multipart_split_start = b'\r\n' + multipart_split_start
			parts = value.split(multipart_split_start)
			for part_item in parts:
				data_item = {}
				item_split_index = part_item.find(b'\r\n\r\n')
				if item_split_index < 0:
					continue
				data_item[''] = part_item[item_split_index + 4:]
				line_split = part_item[0:item_split_index].split(b'\r\n')
				for line_item in line_split:
					idx = line_item.find(b': ')
					if idx >= 0:
						key_name = mousechsh_codec(
							line_item[0: idx],
							source_type=mousechsh_code_util_type_bytes,
							target_type=mousechsh_code_util_type_utf8string
						)
						data_item[key_name.lower()] = line_item[idx + 2:]
						if key_name.lower() == 'content-disposition':
							line_item = data_item[key_name.lower()]
							line_item_split = line_item.split(b'; ')
							data_item[key_name.lower()] = mousechsh_codec(
								line_item_split[0],
								source_type=mousechsh_code_util_type_bytes,
								target_type=mousechsh_code_util_type_utf8string
							)
							for i in range(1, len(line_item_split)):
								line_item = line_item_split[i]
								idx = line_item.find(b'=')
								data_item[mousechsh_codec(
									line_item[0:idx],
									source_type=mousechsh_code_util_type_bytes,
									target_type=mousechsh_code_util_type_utf8string
								).lower()] = mousechsh_codec(
									line_item[idx+1:],
									source_type=mousechsh_code_util_type_bytes,
									target_type=mousechsh_code_util_type_utf8string
								).strip('"')
						else:
							data_item[key_name.lower()] = mousechsh_codec(
								line_item[idx + 2:],
								source_type=mousechsh_code_util_type_bytes,
								target_type=mousechsh_code_util_type_utf8string
							)
				if 'name' in data_item:
					self.__data[data_item['name']] = data_item

	def to_string(self):
		result = ''
		for item in self.__data:
			result += '--' + self.__multipart_split + '\r\n'
			data_item = self.__data[item]
			if 'content-disposition' in data_item:
				result += 'Content-Disposition: ' + data_item['content-disposition']
				if 'name' in data_item:
					result += '; name="' + data_item['name'] + '"'
				if 'filename' in data_item:
					result += '; filename="' + data_item['filename'] + '"'
				result += '\r\n'
			if 'content-type' in data_item:
				result += 'Content-Type: ' + data_item['content-type']
				result += '\r\n'
			if 'filename' in data_item:
				result += '\r\n<<binary length=' + str(len(data_item[''])) + '>>\r\n'
			else:
				result += '\r\n' + mousechsh_codec(
					data_item[''],
					source_type=mousechsh_code_util_type_bytes,
					target_type=mousechsh_code_util_type_utf8string
				) + '\r\n'
		result += '--' + self.__multipart_split + '--'
		return result

	def to_hex(self):
		result = b''
		multipart_split = mousechsh_codec(
			self.__multipart_split,
			source_type=mousechsh_code_util_type_utf8string,
			target_type=mousechsh_code_util_type_bytes
		)
		for item in self.__data:
			result += b'--' + multipart_split + b'\r\n'
			data_item = self.__data[item]
			if 'content-disposition' in data_item:
				result += 'Content-Disposition: ' + mousechsh_codec(
					data_item['content-disposition'],
					source_type=mousechsh_code_util_type_utf8string,
					target_type=mousechsh_code_util_type_bytes
				)
				if 'name' in data_item:
					result += b'; name="' + mousechsh_codec(
						data_item['name'],
						source_type=mousechsh_code_util_type_utf8string,
						target_type=mousechsh_code_util_type_bytes
					) + b'"'
				if 'filename' in data_item:
					result += b'; filename="' + mousechsh_codec(
						data_item['filename'],
						source_type=mousechsh_code_util_type_utf8string,
						target_type=mousechsh_code_util_type_bytes
					) + b'"'
				result += b'\r\n'
			if 'content-type' in data_item:
				result += b'Content-Type: ' + mousechsh_codec(
					data_item['content-type'],
					source_type=mousechsh_code_util_type_utf8string,
					target_type=mousechsh_code_util_type_bytes
				)
				result += b'\r\n'
			if 'filename' in data_item:
				result += b'\r\n' + data_item[''] + b'\r\n'
			else:
				result += b'\r\n' + data_item[''] + b'\r\n'
		result += b'--' + multipart_split + b'--'
		return result

	def __len__(self):
		length = len(self.__data)
		return length if length else 1
